home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / idioms.lha / idioms / fvideo.c < prev    next >
C/C++ Source or Header  |  1993-08-08  |  5KB  |  203 lines

  1. /* Copyright (c) 1992 by AT&T Bell Laboratories. */
  2. /* Advanced C++ Programming Styles and Idioms */
  3. /* James O. Coplien */
  4. /* All rights reserved. */
  5.  
  6. #include <generic.h>
  7. #include <iostream.h>
  8. #include "curses.h"
  9.  
  10. #define LocalScope(function) struct name3(function,Local,Scope) {    \
  11. void *parent; name3(function,Local,Scope)(void *p) { parent = p; } public
  12. #define EndLocalScope } local(this)
  13. #define EndOuterScope } local(0)
  14. #define Parent(type,c) ((name3(type,Local,Scope)*)(c)->parent)
  15.  
  16. void main()
  17. {
  18.     LocalScope(BallGame):
  19.         void DrawSides() {
  20.             for(int i = 0; i < 66; i++) mvaddch(0, i, 'S');
  21.             for(i = 0; i < 13; i++) {
  22.                 mvaddch(i, 0, 'S');
  23.                 mvaddch(i, 65, 'S');
  24.             }
  25.             leftWall = 0;
  26.             rightWall = 65;
  27.         }
  28.  
  29.         struct Ball {
  30.             int yposition, xposition;
  31.             int yspeed, xspeed;
  32.             Ball() {
  33.                 yposition = 6;
  34.                 xposition = 33;
  35.                 yspeed = 1;
  36.                 xspeed = 1;
  37.             }
  38.         } ball;
  39.  
  40.         struct Bat {
  41.             int yposition, position, length, xspeed;
  42.             Bat() { position = 40;
  43.                 yposition = 11;
  44.                 length = 4;
  45.                 xspeed = 0;
  46.             }
  47.         } bat;
  48.  
  49.         void DrawBat() {
  50.             for (int i = bat.position; i < bat.position + bat.length; i++) {
  51.                 mvaddch(bat.yposition, i, 'b');
  52.             }
  53.         }
  54.  
  55.         void EraseBat() {
  56.             for (int i = bat.position; i < bat.position + bat.length; i++) {
  57.                 mvaddch(bat.yposition, i, ' ');
  58.             }
  59.         }
  60.  
  61.         short leftWall, rightWall;
  62.  
  63.         int score;
  64.     
  65.         void DrawWall() {
  66.             for(int i = 0; i < 66; i++) {
  67.                 mvaddch(3, i, 'W');
  68.                 mvaddch(4, i, 'W');
  69.                 mvaddch(5, i, 'W');
  70.             }
  71.         }
  72.  
  73.         char ballIsInPlay() {
  74.             return ball.xposition < rightWall &&
  75.               ball.xposition > leftWall &&
  76.               ball.yposition <= bat.yposition;
  77.         }
  78.  
  79.         void PlayGame() {
  80.             LocalScope(PlayGame):
  81.                 char key;    // from keyboard
  82.  
  83.                 short ballsLeft;
  84.                 void PlayABall() {
  85.                     LocalScope(PlayABall):
  86.                         void CheckBallPosition() {
  87.                             PlayGameLocalScope *p = Parent(PlayGame, this);
  88.                             BallGameLocalScope *p2 = Parent(BallGame, p);
  89.                             int &y = p2->ball.yposition;
  90.                             int &x = p2->ball.xposition;
  91.                             if (x <= p2->leftWall+1 ||
  92.                                 x >= p2->rightWall-1) {
  93.                                 p2->ball.xspeed = -p2->ball.xspeed;
  94.                             }
  95.                             if (y <= 0) {
  96.                                 p2->ball.yspeed = -p2->ball.yspeed;
  97.                             }
  98.                             char c = mvinch(y + p2->ball.yspeed,
  99.                                 x + p2->ball.xspeed);
  100.                             switch (c) {
  101.                             case 'W':
  102.                                 mvaddch(y + p2->ball.yspeed,
  103.                                     x + p2->ball.xspeed,
  104.                                     ' ');
  105.                                 p2->score++;
  106.                             case 'b':
  107.                                 p2->ball.yspeed = -p2->ball.yspeed;
  108.                                 p2->ball.xspeed = p2->bat.xspeed;
  109.                                 break;
  110.                             }
  111.                         }
  112.  
  113.                         void MoveBall() {
  114.                             PlayGameLocalScope *p = Parent(PlayGame, this);
  115.                             BallGameLocalScope *p2 = Parent(BallGame, p);
  116.                             mvaddch(p2->ball.yposition,
  117.                                 p2->ball.xposition, ' ');
  118.                             p2->ball.xposition += p2->ball.xspeed;
  119.                             p2->ball.yposition += p2->ball.yspeed;
  120.                             mvaddch(p2->ball.yposition,
  121.                                 p2->ball.xposition, 'O');
  122.                         }
  123.  
  124.                         void MoveBat(char key) {
  125.                             LocalScope(MoveBat):
  126.                                 void MoveLeft(Bat& bat) {
  127.                                     PlayABallLocalScope *p = Parent(PlayABall, this);
  128.                                     PlayGameLocalScope *p2 = Parent(PlayGame, p);
  129.                                     Parent(BallGame, p2)->EraseBat();
  130.                                     if (bat.position > Parent(BallGame, p2)->leftWall) {
  131.                                         bat.position--;
  132.                                     }
  133.                                     Parent(BallGame, p2)->DrawBat();
  134.                                 }
  135.  
  136.                                 void MoveRight(Bat& bat) {
  137.                                     PlayABallLocalScope *p = Parent(PlayABall, this);
  138.                                     PlayGameLocalScope *p2 = Parent(PlayGame, p);
  139.                                     Parent(BallGame, p2)->EraseBat();
  140.                                     if (bat.position < Parent(BallGame, p2)->rightWall - bat.length) {
  141.                                         bat.position++;
  142.                                     }
  143.                                     Parent(BallGame, p2)->DrawBat();
  144.                                 }
  145.                             EndLocalScope;
  146.  
  147.                             PlayGameLocalScope *p = Parent(PlayGame, this);
  148.                             switch (key) {
  149.                             case 'l':
  150.                                 local.MoveLeft(Parent(BallGame, p)->bat);
  151.                                 Parent(BallGame, p)->bat.xspeed = -1;
  152.                                 break;
  153.                             case 'r':
  154.                                 local.MoveRight(Parent(BallGame, p)->bat);
  155.                                 Parent(BallGame, p)->bat.xspeed = 1;
  156.                                 break;
  157.                             default:
  158.                                 break;
  159.                             }
  160.                         }
  161.                     EndLocalScope;
  162.  
  163.                     while (Parent(BallGame, this)->ballIsInPlay()) {
  164.                         local.CheckBallPosition();    
  165.                         local.MoveBall();
  166.                         refresh();
  167.                         key = getch();
  168.                         local.MoveBat(key);
  169.                     }
  170.                 }
  171.             EndLocalScope;
  172.  
  173.             local.ballsLeft = 4;
  174.             while (local.ballsLeft > 0) {
  175.                 refresh();
  176.                 local.key = getch();
  177.                 local.PlayABall();
  178.                 --local.ballsLeft;
  179.             }
  180.         }
  181.  
  182.     EndOuterScope;
  183.  
  184.     int bestScore = 0;
  185.  
  186.     initscr();
  187.     cbreak();
  188.     noecho();
  189.  
  190.     local.DrawSides();
  191.     local.DrawBat();
  192.  
  193.     for (;;) {
  194.         local.score = 0;
  195.         local.DrawWall();
  196.         local.PlayGame();
  197.         if (local.score > bestScore) {
  198.             bestScore = local.score;
  199.         }
  200.         cout << "best score is " << bestScore << "\n";
  201.     }
  202. }
  203.